﻿#include "networkcommunication.h"

NetworkCommunication::NetworkCommunication(CommunicationProtocol protocal, networkParameters netPara)
    : PLC_Interface_Base(CommunicationType::NetWork, protocal),
      parameters(netPara)
{
    //生成套接字tcpSocket
    tcpSocket = NULL;
    tcpSocket = new QTcpSocket;

    //Tcp断开连接时触发的槽函数
    connect(tcpSocket,&QTcpSocket::disconnected,[=](){
        //TCP断开连接
        DisConnect();
    });
}

// TCP连接函数
bool NetworkCommunication::Connect()
{
    //以防万一，取消当前所有连接，重置套接字
    tcpSocket->abort();

    //进行当前连接，连接至指定从站的指定端口
    tcpSocket->connectToHost(QHostAddress(parameters.ipAddress),parameters.portAddress);

    //判断连接是否成功，连接成功后进行提示并将按钮设置为断开
    if(!tcpSocket->waitForConnected(WAITE_FOR_CONNECT))
    {
        networkStatus = false;
        emit connectionChangedSignal(networkStatus);

        return false;
    }
    else
    {
        //设置TCP连接状态标识符为连接
        networkStatus = true;
        emit connectionChangedSignal(networkStatus);

        return true;
    }
}

// TCP断开函数
void NetworkCommunication::DisConnect()
{
    //设置TCP连接状态标识符为断开
    networkStatus = false;
    emit connectionChangedSignal(networkStatus);

    //断开与服务器的连接
    tcpSocket->disconnectFromHost();
    //关闭套接字
    tcpSocket->close();

    //清空请求报文数组
    ReceiveMessage.clear();
}

//报文发送函数
int NetworkCommunication::MessageSend(const QByteArray &arr)
{
    if(networkStatus)
    {
        tcpSocket->write(arr);
        networkSendIdentifier = true;

        emit requestMessageSendOverSignal();
    }
    else
    {
        networkSendIdentifier = false;

        emit connectionChangedSignal(networkStatus);
        return 0;
    }

    for(resendNumber = 0; resendNumber < RESENDNUMBER; resendNumber++)
    {
        if(tcpSocket->waitForReadyRead(WAITE_FOR_RESPONSE))
        {
            networkSendIdentifier = false;

            return 1;
        }

        //使用TCP向目标从站重新传输请求报文
        tcpSocket->write(RequestMessage);
        networkSendIdentifier = true;

        emit requestMessageSendOverSignal();
    }

    //重传次数费完
    emit resendMessageFail();

    //清空请求报文数组
    RequestMessage.clear();
    networkSendIdentifier = false;

    return 0;
}

//报文接收函数
bool NetworkCommunication::MessageReceive(QByteArray &arr)
{
    if(networkStatus)
    {
        arr = tcpSocket->readAll();
        networkSendIdentifier = false;

        emit receivedAMessageSignal();

        return true;
    }

    emit connectionChangedSignal(networkStatus);
    return false;
}



